﻿package com.winglish.as3.loader{
	import flash.events.EventDispatcher;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.ProgressEvent;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.System;
	
	public class XMLLoader extends EventDispatcher{

		private var xml: XML;
		private var obj: Object;
		private var xmlUrl: String;
		private var xmlLoader: URLLoader;
		private var isConnected: Boolean;
		private var request: URLRequest;
		
		public function XMLLoader( url: String = null ){
			xmlUrl = url;
			init();
		}
		
		private function init(): void{
			if( xmlUrl ) load( xmlUrl );
		}
		
		public function load( url: String = null ): void{
			if( url ) request = new URLRequest( url );
			xml = new XML();
			xmlLoader = new URLLoader();
			xmlLoader.addEventListener( Event.COMPLETE, onCompleteHnadler );
			xmlLoader.addEventListener( Event.OPEN, onOpenHandler );
			xmlLoader.addEventListener( HTTPStatusEvent.HTTP_STATUS, onHttpHnadler );
			xmlLoader.addEventListener( ProgressEvent.PROGRESS, onProgressHnadler );
			xmlLoader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityHnadler );
			xmlLoader.addEventListener( IOErrorEvent.IO_ERROR, onIoErrorHnadler );
			xmlLoader.load( request );
		}
		
		private function onCompleteHnadler( e: Event ): void{

			try{
				xml = XML( xmlLoader.data );
				obj = XMLparsingToObject( xml );
			}catch( e: Error ){
				xmlLoader.load( request );
				trace( e );
			}			

			isConnected = false;
			if( e != null ) dispatchEvent( new Event( Event.COMPLETE ) );
		}
		private function onOpenHandler( e: Event ): void{
			isConnected = true;
			if( e != null ) dispatchEvent( new Event( Event.OPEN ) );
		}
		
		public function getResult(): XML{
			return xml;
		}
		public function getObject(): Object{
			return obj;
		}
		public function stop(): void{
			if( isConnected ) xmlLoader.close();
			isConnected = false;
		}

		private function onHttpHnadler( e: HTTPStatusEvent ): void{
			dispatchEvent( new HTTPStatusEvent( HTTPStatusEvent.HTTP_STATUS ) );
		}
		
		private function onProgressHnadler( e: ProgressEvent ): void{
			dispatchEvent( new ProgressEvent( ProgressEvent.PROGRESS ) );
		}
		
		private function onSecurityHnadler( e: SecurityErrorEvent ): void{
			dispatchEvent( new SecurityErrorEvent( SecurityErrorEvent.SECURITY_ERROR ) );
		}
		
		private function onIoErrorHnadler( e: IOErrorEvent ): void{
			dispatchEvent( new IOErrorEvent( IOErrorEvent.IO_ERROR ) );
		}	
		
		private function XMLparsingToObject( xml: XML ): Object{
			var ary: Array = new Array();
			var xmlObj: Object = new Object();
			xmlObj.len = 0;
			var xmlList: XMLList = xml.children();
			for each( var xmlElement: XML in xmlList ){				
				if( xmlElement.text() != undefined ){
					xmlObj[ xmlElement.name() ] = xmlElement.text();							
					xmlObj.len++;
				}
				ary.push( xmlElement.name() );
				xmlObj[ "key" ] = ary;
				if( xmlElement.hasComplexContent() ){
					var elementObj: Object = XMLparsingToObject( xmlElement );
					xmlObj[ xmlElement.name() ] = elementObj;
				} 
			}			
			return xmlObj;
		}
	}
}